package com.joshjung.hover.interactive
{
    import com.joshjung.collections.ILLIdentifiable;
    import com.joshjung.collections.LinkedList;
    import com.joshjung.echosurf.IClientable;
    import com.joshjung.hover.Hover;
    import com.joshjung.hover.functional.KeyboardResponder;
    import com.joshjung.hover.functional.Viewport;
    import com.joshjung.hover.functional.Weapon;
    import com.joshjung.hover.functional.WeaponBarrel;
    import com.joshjung.hover.interactive.projectiles.Bullet;
    import com.joshjung.hover.interfaces.IByteArrayable;
    import com.joshjung.hover.interfaces.IKeyboardResponder;

    import flash.events.Event;
    import flash.geom.Point;
    import flash.ui.Keyboard;
    import flash.utils.ByteArray;

    public class HoverCraft extends PhysicObject implements IKeyboardResponder, IClientable, IByteArrayable
    {
        //---------------------------------------------------------------------
        //
        //  Static Variables
        //
        //---------------------------------------------------------------------
        public static const ACCEL : int = 0;
        public static const LEFT : int = 1;
        public static const RIGHT : int = 2;
        public static const DECEL : int = 3;
        public static const START_FIRING : int = 4;
        public static const STOP_FIRING : int = 5;

        //---------------------------------------------------------------------
        //
        //  Variables
        //
        //---------------------------------------------------------------------
        protected var acceleration : Number = 500;

        // Used for keys...
        protected var accel : Boolean = false;
        protected var left : Boolean = false;
        protected var right : Boolean = false;
        protected var decel : Boolean = false;
        protected var firing : Boolean = false;

        public var networkPlayer : Boolean = false;

        public var color : uint = 0x00FF00;

        protected var weapon : Weapon;

        protected var kb : KeyboardResponder = new KeyboardResponder();

        protected var _clientID : int;

        public function get clientID() : int
        {
            return _clientID;
        }

        public function set clientID(value : int) : void
        {
            _clientID = value;

            color = Hover.COLORS[_clientID];
        }

        //---------------------------------------------------------------------
        //
        //  Constructor
        //
        //---------------------------------------------------------------------
        /**
         *  Constructor
         */
        public function HoverCraft(viewport : Viewport, loopList : LinkedList)
        {
            super(viewport, loopList);

            this.networkPlayer = networkPlayer;

            initDefaultWeapon();
        }

        //---------------------------------------------------------------------
        //
        //  Methods
        //
        //---------------------------------------------------------------------
        public function initDefaultWeapon() : void
        {
            var weaponBarrels : Array = [];

            weapon = new Weapon(this, weaponBarrels);

            weaponBarrels.push(new WeaponBarrel(weapon, new Point(0, 0), 0, Bullet, 10, 500));
        }

        override public function loop(elapsed : Number) : void
        {
            if (kb.keysDown[Keyboard.LEFT])
                act(HoverCraft.LEFT);
            if (kb.keysDown[Keyboard.RIGHT])
                act(HoverCraft.RIGHT);
            if (kb.keysDown[Keyboard.UP])
                act(HoverCraft.ACCEL);
            if (kb.keysDown[Keyboard.DOWN])
                act(HoverCraft.DECEL);
            if (kb.keyDowns[Keyboard.SPACE])
                act(HoverCraft.START_FIRING);
            if (kb.keyUps[Keyboard.SPACE])
                act(HoverCraft.STOP_FIRING);

            if (accel)
            {
                var cos : Number = Math.cos(rotation * 0.0174532925);
                var sin : Number = Math.sin(rotation * 0.0174532925);

                speed.x += cos * acceleration * elapsed;
                speed.y += sin * acceleration * elapsed;
            }
            if (left)
            {
                rotation -= 200 * elapsed;
            }
            if (right)
            {
                rotation += 200 * elapsed;
            }
            if (decel)
            {
                var cos : Number = Math.cos(rotation * 0.0174532925);
                var sin : Number = Math.sin(rotation * 0.0174532925);

                speed.x -= cos * acceleration * elapsed;
                speed.y -= sin * acceleration * elapsed;
            }

            super.loop(elapsed);

            accel = left = right = decel = false;

            render();

            kb.reset();
        }

        protected function render() : void
        {
            graphics.clear();

            graphics.lineStyle(3, 0x000000);
            graphics.beginFill(color, 1);
            graphics.moveTo(10, 0);
            graphics.lineTo(-10, 8);
            graphics.lineTo(-10, -8);
            graphics.lineTo(10, 0);
            graphics.endFill();

            alpha = networkPlayer ? 0.4 : 1.0;
        }

        public function act(action : int) : void
        {
            accel = accel || action == ACCEL;
            left = left || action == LEFT;
            right = right || action == RIGHT;
            decel = decel || action == DECEL;

            if (action == START_FIRING)
            {
                weapon.startFiring();
            }
            else if (action == STOP_FIRING)
            {
                weapon.stopFiring();
            }
        }

        public function keyDown(keyCode : uint) : void
        {
            kb.keyDown(keyCode);
        }

        public function keyUp(keyCode : uint) : void
        {
            kb.keyUp(keyCode);
        }

        public function toBA(ba : ByteArray) : void
        {
            ba.writeFloat(x);
            ba.writeFloat(y);
            ba.writeFloat(rotation);
        }

        public function fromBA(ba : ByteArray) : void
        {
            x = ba.readFloat();
            y = ba.readFloat();
            rotation = ba.readFloat();
        }
    }
}
